import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.sql.*;

/**
 * A JPanel for deleting a profile, as well as editing its password.
 *
 * @author Jacel Evasco
 * @author Christian Rosquita
 * @author Roselle Nympha Lim
 * @version 1.0
 */
public class ProfileEditor extends JPanel {

    private JPanel labels = new JPanel();
    private JPanel fields = new JPanel();
    private JPanel buttons = new JPanel();
    private JPanel labelsAndFields = new JPanel();
    private JTextField iD = new JTextField();
    private JPasswordField oldPin = new JPasswordField();
    private JPasswordField newPin = new JPasswordField();
    private JPasswordField confirmPin = new JPasswordField();
    private JButton okay = new JButton("okay");
    private JButton deleteProfile = new JButton("delete");
    private JLabel[] fieldLabels = {
        new JLabel("ID number", SwingConstants.RIGHT),
        new JLabel("Old PIN", SwingConstants.RIGHT),
        new JLabel("New PIN", SwingConstants.RIGHT),
        new JLabel("Confirm PIN", SwingConstants.RIGHT) };

    Connection connection = null;
    PreparedStatement preparedStatement = null;
    ResultSet resultSet = null;

    public ProfileEditor() {
        assemble();
        configure();
        design();
        setTriggers();
    }// end of ProfileMenu()

    // a method that empties the text fields
    public void cleanUp() {
        oldPin.setText("");
        newPin.setText("");
        confirmPin.setText("");
    } // end of cleanUp method

    private void prepareConnection() {
        try {
            connection = DatabaseUtility.prepareConnection();
        } catch (Exception e) {
            e.printStackTrace();
        }
    } // end of prepareConnection method

    private void assemble() {
        // labels
        labels.setLayout(new BoxLayout(labels, BoxLayout.Y_AXIS));
        labels.add(fieldLabels[0]);
        labels.add(Box.createRigidArea(new Dimension(0, 15)));
        labels.add(fieldLabels[1]);
        labels.add(Box.createRigidArea(new Dimension(0, 15)));
        labels.add(fieldLabels[2]);
        labels.add(Box.createRigidArea(new Dimension(0, 15)));
        labels.add(fieldLabels[3]);
        // fields
        fields.setLayout(new BoxLayout(fields, BoxLayout.Y_AXIS));
        fields.add(iD);
        fields.add(Box.createRigidArea(new Dimension(0, 15)));
        fields.add(oldPin);
        fields.add(Box.createRigidArea(new Dimension(0, 15)));
        fields.add(newPin);
        fields.add(Box.createRigidArea(new Dimension(0, 15)));
        fields.add(confirmPin);
        // fields and labels
        labelsAndFields.setLayout(new BoxLayout(labelsAndFields,
            BoxLayout.X_AXIS));
        labelsAndFields
            .add(Box.createRigidArea(new Dimension(33, 0)));
        labelsAndFields.add(labels);
        labelsAndFields
            .add(Box.createRigidArea(new Dimension(30, 0)));
        labelsAndFields.add(fields);
        // buttons
        buttons.setLayout(new BoxLayout(buttons, BoxLayout.X_AXIS));
        buttons.add(Box.createRigidArea(new Dimension(173, 0)));
        buttons.add(deleteProfile);
        buttons.add(Box.createRigidArea(new Dimension(16, 0)));
        buttons.add(okay);
        // this
        this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
        this.add(Box.createRigidArea(new Dimension(0, 25)));
        this.add(labelsAndFields);
        this.add(Box.createRigidArea(new Dimension(0, 17)));
        this.add(buttons);

    }// end of assemble()

    private void configure() {
        iD.setEditable(false);
        fetchID();
    }// end of configure()

    private void design() {
        // sizes
        okay.setPreferredSize(new Dimension(100, 28));
        okay.setMinimumSize(new Dimension(100, 28));
        okay.setMaximumSize(new Dimension(100, 28));
        deleteProfile.setPreferredSize(new Dimension(100, 28));
        deleteProfile.setMinimumSize(new Dimension(100, 28));
        deleteProfile.setMaximumSize(new Dimension(100, 28));
        fieldLabels[0].setPreferredSize(new Dimension(110, 28));
        fieldLabels[0].setMinimumSize(new Dimension(110, 28));
        fieldLabels[0].setMaximumSize(new Dimension(110, 28));
        fieldLabels[1].setPreferredSize(new Dimension(110, 28));
        fieldLabels[1].setMinimumSize(new Dimension(110, 28));
        fieldLabels[1].setMaximumSize(new Dimension(110, 28));
        fieldLabels[2].setPreferredSize(new Dimension(110, 28));
        fieldLabels[2].setMinimumSize(new Dimension(110, 28));
        fieldLabels[2].setMaximumSize(new Dimension(110, 28));
        fieldLabels[3].setPreferredSize(new Dimension(110, 28));
        fieldLabels[3].setMinimumSize(new Dimension(110, 28));
        fieldLabels[3].setMaximumSize(new Dimension(110, 28));
        iD.setPreferredSize(new Dimension(287, 28));
        iD.setMinimumSize(new Dimension(287, 28));
        iD.setMaximumSize(new Dimension(287, 28));
        oldPin.setPreferredSize(new Dimension(287, 28));
        oldPin.setMinimumSize(new Dimension(287, 28));
        oldPin.setMaximumSize(new Dimension(287, 28));
        newPin.setPreferredSize(new Dimension(287, 28));
        newPin.setMinimumSize(new Dimension(287, 28));
        newPin.setMaximumSize(new Dimension(287, 28));
        confirmPin.setPreferredSize(new Dimension(287, 28));
        confirmPin.setMinimumSize(new Dimension(287, 28));
        confirmPin.setMaximumSize(new Dimension(287, 28));
        labelsAndFields.setPreferredSize(new Dimension(500, 159));
        labelsAndFields.setMinimumSize(new Dimension(500, 159));
        labelsAndFields.setMaximumSize(new Dimension(500, 159));
        buttons.setPreferredSize(new Dimension(500, 28));
        buttons.setMinimumSize(new Dimension(500, 28));
        buttons.setMaximumSize(new Dimension(500, 28));
        this.setPreferredSize(new Dimension(500, 284));
        this.setMinimumSize(new Dimension(500, 284));
        this.setMaximumSize(new Dimension(500, 284));

        // font styles
        Font font = new Font("Segoe UI Light", Font.PLAIN, 16);
        Font labelFont = new Font("Segoe UI", Font.BOLD, 14);
        Font buttonFont = new Font("Segoe UI", Font.BOLD, 14);
        iD.setFont(font);
        oldPin.setFont(font);
        newPin.setFont(font);
        confirmPin.setFont(font);
        okay.setFont(buttonFont);
        deleteProfile.setFont(buttonFont);
        fieldLabels[0].setFont(labelFont);
        fieldLabels[1].setFont(labelFont);
        fieldLabels[2].setFont(labelFont);
        fieldLabels[3].setFont(labelFont);
        // borders
        iD.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
        oldPin.setBorder(BorderFactory.createLineBorder(Color.BLACK,
            1));
        newPin.setBorder(BorderFactory.createLineBorder(Color.BLACK,
            1));
        confirmPin.setBorder(BorderFactory.createLineBorder(
            Color.BLACK, 1));
        // backgrounds
        labels.setOpaque(false);
        fields.setOpaque(false);
        buttons.setOpaque(false);
        labelsAndFields.setOpaque(false);
        // buttons
        okay.setContentAreaFilled(false);
        deleteProfile.setContentAreaFilled(false);

    }// end of design()

    public void fetchID() {
        prepareConnection();
        String query = "SELECT * FROM requirementstrackerschema.student"
            + " WHERE isLoggedIn = 1";
        try {
            preparedStatement = connection.prepareStatement(query);
            resultSet = preparedStatement.executeQuery();

            if (resultSet.next()) {
                String profileID = resultSet.getString("studentID");
                iD.setText(profileID);
            } else {
                iD.setText("");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } // end of try-catch
    }// end of fetchID()

    private void setTriggers() {
        ActionListener actionTrigger = new ActionListener() {
            public void actionPerformed(ActionEvent anActionEvent) {
                if (anActionEvent.getSource() == okay) {
                    verifyInput();
                } else if (anActionEvent.getSource() == deleteProfile) {
                    verifyOldPin();
                }
            }
        }; // end of viewerTrigger
        okay.addActionListener(actionTrigger);
        deleteProfile.addActionListener(actionTrigger);
    } // end of setTriggers

    // a method that checks whether all inputs are valid and correct
    private void verifyInput() {
        prepareConnection();

        String verify = "SELECT * FROM requirementstrackerschema.student"
            + " WHERE studentID = ? AND pin = ?";

        try {
            preparedStatement = connection.prepareStatement(verify);
            preparedStatement.setString(1, iD.getText());
            preparedStatement.setString(2, oldPin.getText());
            resultSet = preparedStatement.executeQuery();

            // if valid
            if (resultSet.next()) {
                verifyNewPin();
            } else { // if no such pin
                JOptionPane.showMessageDialog(null,
                    "Old pin is incorrect.");
            } // end of if-else
        } catch (Exception e) {
            e.printStackTrace();
        } // end of try-catch
    } // end of verifyIDPin method

    // a method that checks whether the new pins match
    private void verifyNewPin() {
        String pin1 = newPin.getText();
        String pin2 = confirmPin.getText();

        // if pins match
        if (pin1.equals(pin2)) {
            updatePin();
        } else { // if do not match
            JOptionPane.showMessageDialog(null, "Pins don't match");
        } // end of if-else
    } // end of verifyNewPin method

    // a method that updates the database
    private void updatePin() {
        prepareConnection();

        String updateQuery = "UPDATE requirementstrackerschema.student"
            + " SET pin = ? WHERE studentID = ? AND isLoggedIn = '1'";

        try {
            preparedStatement = connection
                .prepareStatement(updateQuery);
            preparedStatement.setString(1, newPin.getText());
            preparedStatement.setString(2, iD.getText());
            preparedStatement.executeUpdate();

            JOptionPane.showMessageDialog(null,
                "Pin successfully changed!");

            cleanUp();
            JOptionPane.getRootFrame().dispose();

        } catch (Exception e) {
            e.printStackTrace();
        } // end of try-catch
    } // end of updatePin method

    // a method that checks whether the pin inputted is valid
    private void verifyOldPin() {
        String verifyPinQuery = "SELECT * FROM requirementstrackerschema.student"
            + " WHERE studentID = ? AND pin = ? AND isLoggedIn = '1'";

        try {
            preparedStatement = connection
                .prepareStatement(verifyPinQuery);
            preparedStatement.setString(1, iD.getText());
            preparedStatement.setString(2, oldPin.getText());
            resultSet = preparedStatement.executeQuery();

            // if old pin is correct
            if (resultSet.next()) {
                // confirmDeleteAccount();
                deleteAccount();
            } else { // if pin is wrong
                JOptionPane.showMessageDialog(null,
                    "Pin is incorrect.");
            } // end of if-else
        } catch (Exception e) {
            e.printStackTrace();
        } // end of try-catch
    } // end of verifyOldPin method

    // a method that delete that account record in the database
    private void deleteAccount() {

        String deleteAccountQuery = "DELETE FROM requirementstrackerschema.student"
            + " WHERE studentID = ?";

        try {
            preparedStatement = connection
                .prepareStatement(deleteAccountQuery);
            preparedStatement.setString(1, iD.getText());
            preparedStatement.executeUpdate();

            JOptionPane.showMessageDialog(null,
                "Profile successfully deleted!");

            cleanUp();
            Explorer.getInstance().fetchID();
            Explorer.getInstance().getProfileMenu()
                .getProfilePeeker().fetchID();
            Explorer.getInstance().getProfileMenu()
                .getProfileEditor().cleanUp();
            Explorer.getInstance().getProfileMenu()
                .getProfileEditor().fetchID();
            Explorer.getInstance().getProfileMenu()
                .getProfileAuthenticator().cleanUp();
            Explorer.getInstance().getProfileMenu().getProfileMaker()
                .cleanUp();
            Explorer.getInstance().getRequirementsViewer().getData()
                .refresh();
            Explorer.getInstance().getGoalsViewer().getData()
                .refresh();
            Explorer.getInstance().getGoalsViewer().isDataEmpty();
            Explorer.getInstance().getRequirementsViewer()
                .isDataEmpty();
            Explorer.getInstance().getProfileMenu().getEdit()
                .setEnabled(false);
            Explorer.getInstance().getProfileMenu().getEdit()
                .setVisible(false);

            // show profileAuthenticator
            ((CardLayout) (ProfileMenu.getCards().getLayout())).show(
                ProfileMenu.getCards(), "profileAuthenticator");

        } catch (Exception e) {
            e.printStackTrace();
        } // end of try-catch

    } // end of deleteAccount method
}// end of ProfileEditor